/***********************************************************************
 * Copyright (c) Darren Carlson
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (LGPL)
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public 
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 ***********************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Web;
using System.Xml;
using System.IO;
using System.Net;
using System.Collections;
using System.Security.Cryptography;
using System.Web.Security;
using System.Threading;

namespace OceanDebugger
{
    public partial class DebuggerMain : Form
    {
        Dictionary<int, RequestConfig> requests = new Dictionary<int, RequestConfig>();
        List<RequestConfig> isnmTest = new List<RequestConfig>();
        RequestConfig getFrob;
        RequestConfig getToken;

        public DebuggerMain()
        {
            InitializeComponent();
            createMethods();
            reloadRequestXml();
        }        

        private void createMethods()
        {
            string server = "http://127.0.0.1:3000/v1";
            
            isnmTest.Add(new RequestConfig(server));
            isnmTest.Add(new RequestConfig(server));
            isnmTest.Add(new RequestConfig(server));
            isnmTest.Add(new RequestConfig(server));
            isnmTest[0].xmlPath = "R:/projects/2007_04_19 - PhD/Xml Specifications/ISNM Test/ISNMAnnotation_ISNM.xml";
            isnmTest[1].xmlPath = "R:/projects/2007_04_19 - PhD/Xml Specifications/ISNM Test/ISNMAnnotation_ISNMEdge.xml";           
            isnmTest[2].xmlPath = "R:/projects/2007_04_19 - PhD/Xml Specifications/ISNM Test/ISNMAnnotation_NearISNMEdge.xml";
            isnmTest[3].xmlPath = "R:/projects/2007_04_19 - PhD/Xml Specifications/ISNM Test/ISNMAnnotation_Koberg.xml";
            
            // Resource request

            RequestConfig c1 = new RequestConfig(server);
            c1.BaseURL = "/resources/request";
            c1.WebMethod = "POST";
            c1.PostDataTarget = txtRawRequest;
            tabRequest.Tag = c1;
            //requests.Add(0, c1);
            
            // Resource annotate
            RequestConfig c2 = new RequestConfig(server);
            c2.BaseURL = "/resource/contextualize";
            c2.WebMethod = "POST";
            c2.PostDataTarget = txtRawAnnotate;
            tabAnnotate.Tag = c2;
            //requests.Add(1, c2);

            // Resource update
            RequestConfig c3 = new RequestConfig(server);
            c3.BaseURL = "/resource/contextualize";
            c3.WebMethod = "PUT";
            c3.PostDataTarget = txtRawUpdate;
            tabUpdate.Tag = c3;
            //requests.Add(2, c3);

            // Resource delete
            RequestConfig c4 = new RequestConfig(server);           
            c4.BaseURL = "/resource/delete";
            c4.WebMethod = "POST";
            c4.PostDataTarget = txtRawDelete;
            tabDelete.Tag = c4;
            //requests.Add(3, c4);

            // Resolve URI Code
            // /resource/resolve/
            RequestConfig c5 = new RequestConfig(server);
            c5.BaseURL = "/resource/resolve";
            c5.WebMethod = "POST";
            c5.PostDataTarget = txtRawResolve;
            tabResolve.Tag = c5;
            //requests.Add(4, c5);

            RequestConfig c6 = new RequestConfig(server);
            c6.BaseURL = "/resource/rate/";
            c6.WebMethod = "POST";
            c6.PostDataTarget = txtRawRate;
            tabRate.Tag = c6;
            //requests.Add(4, c5);

            // Get frob
            getFrob = new RequestConfig(server);
            getFrob.BaseURL = "/authenticate/frob";
            getFrob.WebMethod = "GET";

            // Get token
            getToken = new RequestConfig(server);
            getToken.BaseURL = "/authenticate/token";
            getToken.WebMethod = "GET";

        }
      
        private void clearStatus()
        {
            txtStatusCode.Clear();
            txtStatusDescription.Clear();
           // webBrowser..Clear();
            //webBrowser.DocumentText = "";
            txtRawResponse.Clear();
            txtMediaType.Clear();
            txtURI.Clear();            
            Application.DoEvents();
        }

        // http://www.blooberry.com/indexdot/html/topics/urlencoding.htm
        private String urlEncode(String url)
        {
            //return HttpUtility.UrlEncode(url, Encoding.UTF8);
            return url;
        }
        
        private void btnCall_Click(object sender, EventArgs e)
        {
            clearStatus();
            RequestConfig c = (RequestConfig)tabRawUpdate.TabPages[tabRawUpdate.SelectedIndex].Tag;
 
            c.CallURL = c.BaseURL + urlEncode("?api_key=" + txtApiKey.Text + "&token=" + txtAuthToken.Text);
            try
            {
                txtRawResponse.Text = doWebCall(c);

            }
            catch
            {

            }                      
        }

        private String doWebCall(RequestConfig config)
        {
            if (config != null)
            {
                Uri address = new Uri(config.CallURL, false);
                txtURI.Text = address.ToString();

                // Create the web request  
                HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;

                // Set method and type
                request.Method = config.WebMethod;
                request.ContentType = config.ContentType;

                try
                {
                    // Write data  
                    if (config.WebMethod == "POST" || config.WebMethod == "PUT")
                    {
                        // Create the data we want to send
                        XmlDocument doc = new XmlDocument();

                        // Create a byte array of the data we want to send  
                        byte[] byteData = UTF8Encoding.UTF8.GetBytes(config.PostData);

                        // Set the content length in the request headers  
                        request.ContentLength = byteData.Length;

                        Stream postStream = request.GetRequestStream();
                        postStream.Write(byteData, 0, byteData.Length);
                        postStream.Close();
                    }

                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    txtStatusCode.Text = response.StatusCode.ToString();
                    txtStatusDescription.Text = response.StatusDescription;
                    txtMediaType.Text = response.ContentType;

                    // Get the response stream  
                    StreamReader reader = new StreamReader(response.GetResponseStream());
                    string tmp =  reader.ReadToEnd();
                    response.Close();
                    return tmp;
                }
                catch (WebException wex)
                {
                    txtStatusDescription.Text = wex.Message;

                    if (wex.Response != null)// || wex.Status != WebExceptionStatus.Timeout)
                    {
                        // Get the response stream  
                        HttpWebResponse errorResponse = (HttpWebResponse)wex.Response;
                        txtStatusCode.Text = errorResponse.StatusCode.ToString();
                        StreamReader reader = new StreamReader(errorResponse.GetResponseStream());
                        txtRawResponse.Text = reader.ReadToEnd();                        
                        reader.Close();
                    }
                    throw wex;
                }
                finally
                {

                }
            }
            return "";
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            DialogResult r = openFileDialog1.ShowDialog();
            if (r == DialogResult.OK)
            {
                txtRequestXmlPath.Text = openFileDialog1.FileName;
                Properties.Settings.Default.Save();
                reloadRequestXml();
            }
        }

        private void reloadRequestXml()
        {
            StreamReader reader = null;
            if (File.Exists(txtRequestXmlPath.Text))
            {
                reader = File.OpenText(txtRequestXmlPath.Text);
                txtRawRequest.Text = reader.ReadToEnd();
                reader.Close();
            }
            if (File.Exists(txtAnnotateXmlPath.Text))
            {
                reader = File.OpenText(txtAnnotateXmlPath.Text);
                txtRawAnnotate.Text = reader.ReadToEnd();
                reader.Close();
            }
            if (File.Exists(txtUpdateXmlPath.Text))
            {
                reader = File.OpenText(txtUpdateXmlPath.Text);
                txtRawUpdate.Text = reader.ReadToEnd();
                reader.Close();
            }
            if (File.Exists(txtDeleteXmlPath.Text))
            {
                reader = File.OpenText(txtDeleteXmlPath.Text);
                txtRawDelete.Text = reader.ReadToEnd();
                reader.Close();
            }
            if (File.Exists(txtRateXMLPath.Text))
            {
                reader = File.OpenText(txtRateXMLPath.Text);
                txtRawRate.Text = reader.ReadToEnd();
                reader.Close();
            }
            if (File.Exists(txtResolveXMLPath.Text))
            {
                reader = File.OpenText(txtResolveXMLPath.Text);
                txtRawResolve.Text = reader.ReadToEnd();
                reader.Close();
            }
        }

        private void btnReload_Click(object sender, EventArgs e)
        {
            reloadRequestXml();
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            this.clearStatus();
            txtAuthToken.Clear();
            txtFrob.Clear();
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            clearStatus();
            RequestConfig c = getFrob;
            c.CallURL = c.BaseURL + urlEncode("/" + txtUserEmail.Text + "?api_key=" + txtApiKey.Text);
            try { txtFrob.Text = doWebCall(c); }
            catch { }
        }

        private void btnGetToken_Click(object sender, EventArgs e)
        {
            clearStatus();
            string sig =
              FormsAuthentication.HashPasswordForStoringInConfigFile(txtSecretKey.Text + txtUserPass.Text + txtFrob.Text, "sha1");
            RequestConfig c = getToken;
            c.CallURL = c.BaseURL + urlEncode("/" + txtFrob.Text + "?sig=" + sig + "&api_key=" + txtApiKey.Text);
            try { txtAuthToken.Text = doWebCall(c); }
            catch { } 
        }
       
        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {            
            Console.WriteLine(sender + ": " + ((TabControl)sender).SelectedIndex);
        }

        private void btnAnnotateBrowse_Click(object sender, EventArgs e)
        {
            DialogResult r = openFileDialog1.ShowDialog();
            if (r == DialogResult.OK)
            {
                txtAnnotateXmlPath.Text = openFileDialog1.FileName;
                Properties.Settings.Default.Save();
                reloadRequestXml();
            }
        }

        private void btnAnnotateRefresh_Click(object sender, EventArgs e)
        {
            this.reloadRequestXml();
        }

        private void btnBrowseUpdate_Click(object sender, EventArgs e)
        {
            DialogResult r = openFileDialog1.ShowDialog();
            if (r == DialogResult.OK)
            {
                txtUpdateXmlPath.Text = openFileDialog1.FileName;
                Properties.Settings.Default.Save();
                reloadRequestXml();
            }
        }

        private void btnReloadUpdate_Click(object sender, EventArgs e)
        {
            reloadRequestXml();
        }

        private void btnBrowseDelete_Click(object sender, EventArgs e)
        {
            DialogResult r = openFileDialog1.ShowDialog();
            if (r == DialogResult.OK)
            {
                txtDeleteXmlPath.Text = openFileDialog1.FileName;
                Properties.Settings.Default.Save();
                reloadRequestXml();
            }
        }

        private void btnReloadDelete_Click(object sender, EventArgs e)
        {
            reloadRequestXml();
        }

        private void btnISNMTest_Click(object sender, EventArgs e)
        {
            foreach (RequestConfig config in isnmTest)
            {
                // Always reload XML data between calls
                StreamReader s = File.OpenText(config.xmlPath);
                config.PostData = s.ReadToEnd();
                s.Close();
                config.CallURL = config.BaseURL + urlEncode("?api_key=" + txtApiKey.Text + "&token=" + txtAuthToken.Text);
                try { this.doWebCall(config); }
                catch { }
                Application.DoEvents();
                Thread.Sleep(1050);
            }
        }

        private void btnBrowseRate_Click(object sender, EventArgs e)
        {
            DialogResult r = openFileDialog1.ShowDialog();
            if (r == DialogResult.OK)
            {
                txtRateXMLPath.Text = openFileDialog1.FileName;
                Properties.Settings.Default.Save();
                reloadRequestXml();
            }
        }

        private void btnReloadRate_Click(object sender, EventArgs e)
        {
            reloadRequestXml();
        }

        private void btnBrowseResolve_Click(object sender, EventArgs e)
        {
            DialogResult r = openFileDialog1.ShowDialog();
            if (r == DialogResult.OK)
            {
                txtResolveXMLPath.Text = openFileDialog1.FileName;
                Properties.Settings.Default.Save();
                reloadRequestXml();
            }
        }

        private void btnReloadResolve_Click(object sender, EventArgs e)
        {
            reloadRequestXml();
        }
    }
}